#!/usr/bin/perl

use Test;

BEGIN {
    $test_count                 = 8;
    $test_nnp_nosuid_transition = 0;

    if (
        system(
"grep -q 1 /sys/fs/selinux/policy_capabilities/nnp_nosuid_transition 2> /dev/null"
        ) == 0
      )
    {
        $test_nnp_nosuid_transition = 1;
        $test_count += 10;
    }

    plan tests => $test_count;
}

$basedir = $0;
$basedir =~ s|(.*)/[^/]*|$1|;

# Remove any leftover programs from prior failed runs.
system("rm -f $basedir/true");

# Set entrypoint type for bounded domain under NNP.
system("chcon -t test_bounded_exec_t $basedir/checkcon");

# Create nosuid mount.
system("mkdir -p $basedir/testdir");
system("mount -t tmpfs -o nosuid none $basedir/testdir");

# Set entrypoint type for bounded domain under nosuid.
system("cp $basedir/checkcon $basedir/testdir");
system("chcon -t test_bounded_exec_t $basedir/testdir/checkcon");

# Transition under NNP to bounded type via setexec.
$result = system(
"$basedir/execnnp -n -- runcon -t test_bounded_t $basedir/checkcon test_bounded_t 2>&1"
);
ok( $result, 0 );    #this should pass

# Transition on nosuid to bounded type via setexec.
$result = system(
"$basedir/execnnp -- runcon -t test_bounded_t $basedir/testdir/checkcon test_bounded_t 2>&1"
);
ok( $result, 0 );    #this should pass

# Automatic transition under NNP to bounded domain via exec.
$result =
  system("$basedir/execnnp -n -- $basedir/checkcon test_bounded_t 2>&1");
ok( $result, 0 );    #this should pass

# Automatic transition on nosuid to bounded domain via exec.
$result =
  system("$basedir/execnnp -- $basedir/testdir/checkcon test_bounded_t 2>&1");
ok( $result, 0 );    #this should pass

# Use true as an entrypoint program to test ability to exec at all.
system("cp /bin/true $basedir/true");
system("cp /bin/true $basedir/testdir/true");

# Set entrypoint type for notbounded domain.
system("chcon -t test_notbounded_exec_t $basedir/checkcon $basedir/true");
system(
"chcon -t test_notbounded_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
);

# Transition under NNP to notbounded domain via setexec.
$result =
  system(
    "$basedir/execnnp -n -- runcon -t test_notbounded_t $basedir/true 2>&1");
ok($result);    #this should fail

# Transition on nosuid to notbounded domain via setexec.
$result =
  system(
    "$basedir/execnnp -- runcon -t test_notbounded_t $basedir/testdir/true 2>&1"
  );
ok($result);    #this should fail

# Automatic transition under NNP to notbounded domain via exec.
$result =
  system("$basedir/execnnp -n -- $basedir/checkcon test_notbounded_t 2>&1");
ok($result);    #this should fail

# Automatic transition on nosuid to notbounded domain via exec.
$result =
  system(
    "$basedir/execnnp -- $basedir/testdir/checkcon test_notbounded_t 2>&1");
ok($result);    #this should fail

if ($test_nnp_nosuid_transition) {

    # Set entrypoint type for nnptransition domain.
    system(
        "chcon -t test_nnptransition_exec_t $basedir/checkcon $basedir/true");
    system(
"chcon -t test_nnptransition_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
    );

    # Transition under NNP to nnptransition domain via setexec.
    $result =
      system(
"$basedir/execnnp -n -- runcon -t test_nnptransition_t $basedir/true 2>&1"
      );
    ok( $result, 0 );    #this should succeed

    # Transition under NNP+nosuid to nnptransition domain via setexec.
    $result =
      system(
"$basedir/execnnp -n -- runcon -t test_nnptransition_t $basedir/testdir/true 2>&1"
      );
    ok($result);         #this should fail

    # Automatic transition under NNP to nnptransition domain via exec.
    $result =
      system(
        "$basedir/execnnp -n -- $basedir/checkcon test_nnptransition_t 2>&1");
    ok( $result, 0 );    #this should succeed

    # Automatic transition under NNP+nosuid to nnptransition domain via exec.
    $result =
      system(
"$basedir/execnnp -n -- $basedir/testdir/checkcon test_nnptransition_t 2>&1"
      );
    ok($result);         #this should fail

    # Set entrypoint type for nosuidtransition domain.
    system(
"chcon -t test_nosuidtransition_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
    );

    # Transition under nosuid to nosuidtransition domain via setexec.
    $result =
      system(
"$basedir/execnnp -- runcon -t test_nosuidtransition_t $basedir/testdir/true 2>&1"
      );
    ok( $result, 0 );    #this should succeed

    # Transition under NNP+nosuid to nosuidtransition domain via setexec.
    $result =
      system(
"$basedir/execnnp -n -- runcon -t test_nosuidtransition_t $basedir/testdir/true 2>&1"
      );
    ok($result);         #this should fail

    # Automatic transition under nosuid to nosuidtransition domain via exec.
    $result =
      system(
"$basedir/execnnp -- $basedir/testdir/checkcon test_nosuidtransition_t 2>&1"
      );
    ok( $result, 0 );    #this should succeed

    # Automatic transition under NNP+nosuid to nosuidtransition domain via exec.
    $result =
      system(
"$basedir/execnnp -n -- $basedir/testdir/checkcon test_nosuidtransition_t 2>&1"
      );
    ok($result);         #this should fail

    # Set entrypoint type for nnpnosuidtransition domain.
    system(
"chcon -t test_nnpnosuidtransition_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
    );

    # Transition under NNP+nosuid to nnpnosuidtransition domain via setexec.
    $result =
      system(
"$basedir/execnnp -n -- runcon -t test_nnpnosuidtransition_t $basedir/testdir/true 2>&1"
      );
    ok( $result, 0 );    #this should succeed

 # Automatic transition under NNP+nosuid to nnpnosuidtransition domain via exec.
    $result =
      system(
"$basedir/execnnp -n -- $basedir/testdir/checkcon test_nnpnosuidtransition_t 2>&1"
      );
    ok( $result, 0 );    #this should succeed
}

# Cleanup.
system("rm -f $basedir/true");
system("umount $basedir/testdir");
system("rmdir $basedir/testdir");

exit;
